classdef Bounded
    properties
        Index
        Hole            % true if it's an outer boundary
        Boundary        % List of points that make the boundary
        BoundingBox     % Minimal bounding box that contains the all the points
        CenterBox       % Center of the bounding box
        DiagonalBox     % Diagonal length of the bounding box
        AreaBox         % Area of the bounding box
        IsSquare
    end
    methods
        function obj = Bounded(points, i, N)
            % Receives a list of points and computes a bounding box
            if nargin > 0
                obj.Index = i;
                obj.Hole = i > N;
                obj.Boundary = points;
                % Find min and max coordinates
                minx = min(points(:,2));
                maxx = max(points(:,2)) + 1;
                miny = min(points(:,1));
                maxy = max(points(:,1)) + 1;
                obj.BoundingBox = [minx, miny, maxx, maxy];
                % Find bbox center
                centerx = (minx + maxx) / 2;
                centery = (miny + maxy) / 2;
                obj.CenterBox = [centerx, centery];
                % Calculate diagonal
                obj.DiagonalBox = pointDistance([minx, miny], [maxx, maxy]);
                % Calculate area
                obj.AreaBox = (maxx - minx) * (maxy - miny);
                % Evaluate if it's squary enough
                perimeter = length(points);
                sidex = maxx - minx;
                sidey = maxy - miny;
                side_factor = max(sidex / sidey, sidey / sidex);
                side_avg = mean([sidex, sidey]);
                obj.IsSquare = side_factor < 2 && perimeter < 4 * side_avg * 1.33; % 1.33 == 33% tolerance
            end
        end
        function inside = pointInBox(obj, point)
            minx = obj.BoundingBox(1);
            miny = obj.BoundingBox(2);
            maxx = obj.BoundingBox(3);
            maxy = obj.BoundingBox(4);
            x = point(1);
            y = point(2);
            inside = x >= minx && x <= maxx && y >= miny && y <= maxy;
        end
        function inside = pointInPoly(obj, point)
            inside = inpolygon(point(1), point(2), obj.Boundary(:,1), obj.Boundary(:,2));
        end
    end
end

